﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using SLogo.Command;
using SLogo.Compile;
using SLogo.Execute;
using SLogo.Helper;

namespace SLogo
{
    class Program
    {
        //输出类型
        private static String _graphicsType = "png";
        // 空白大小
        private static int _marginTop = -1;
        private static int _marginBottom = -1;
        private static int _marginLeft = -1;
        private static int _marginRight = -1;
        //源文件路径
        private static String _path = "";
        //画布大小
        private static int _sizeWidth = 1000;
        private static int _sizeHeight = 1000;

        /// <summary>
        /// 主方法
        /// </summary>
        /// <param name="args">命令行参数</param>
        static void Main(string[] args)
        {
            if (!HandleArgs(args))
            {
                return;
            }
            //判断文件是否存在
            if (!FileHelper.IsFileExist(_path))
            {
                ConsoleHelper.StdErr("指定的源文件不存在，程序退出\n");
                return;
            }
            //读取源文件并进行预处理
            String source = CompileHelper.PreCompile(FileHelper.ReadFile(_path));
            //源代码进栈
            LexicalAnalysis.FilenameStack.Push(_path);
            LexicalAnalysis.SourceCode.Push(source);
            //进行语法分析和语义分析
            SyntaxAndSemanticAnalysis.Program();
            //如果通过编译
            if (SyntaxAndSemanticAnalysis.Success && LexicalAnalysis.Success)
            {
                //初始化海龟
                TurtleCommand.Bottom = _marginBottom;
                TurtleCommand.GraphicsType = _graphicsType;
                TurtleCommand.Height = _sizeHeight;
                TurtleCommand.Left = _marginLeft;
                TurtleCommand.Right = _marginRight;
                TurtleCommand.Top = _marginTop;
                TurtleCommand.Width = _sizeWidth;
                //初始化画板
                TurtleCommand.Init();
                //如果成功执行)
                if (ExecuteSlogo.ExecuteAll(SyntaxAndSemanticAnalysis.IntermediateCodeList))
                {
                    //输出图形
                    TurtleCommand.WriteOutGraphics();
                }
                else
                {
                    ConsoleHelper.StdErr("发生运行时错误，程序退出\n");
                }
            }
            else
            {
                ConsoleHelper.StdErr("编译期间发生错误，程序退出\n");
            }
        }

        //处理命令行参数
        static bool HandleArgs(String[] args)
        {
            int defaultNum = 0;
            for (int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                    case "-m":
                        i++;
                        if (i == args.Length)
                        {
                            ConsoleHelper.StdErr("命令行参数错误：-m参数后必须有正整数\n");
                            return false;
                        }
                        String[] margins = args[i].Split(',');
                        switch(margins.Length)//根据不同的命令长度确定边距参数
                        {
                            case 1:
                                if(int.TryParse(margins[0], out _marginTop) && _marginTop >= 0)
                                {
                                    _marginBottom = _marginTop;
                                    _marginLeft = _marginTop;
                                    _marginRight = _marginTop;
                                    return true;
                                }
                                ConsoleHelper.StdErr("命令行参数错误：-m参数后必须为用半角逗号分割开的正整数\n");
                                return false;
                            case 2:
                                if (int.TryParse(margins[0], out _marginTop) && _marginTop >= 0
                                    && int.TryParse(margins[1], out _marginLeft) && _marginLeft >= 0)
                                {
                                    _marginBottom = _marginTop;
                                    _marginRight = _marginLeft;
                                    return true;
                                }
                                ConsoleHelper.StdErr("命令行参数错误：-m参数后必须为用半角逗号分割开的正整数\n");
                                return false;
                            case 4:
                                if (int.TryParse(margins[0], out _marginTop) && _marginTop >= 0
                                    && int.TryParse(margins[1], out _marginBottom) && _marginBottom >= 0
                                    && int.TryParse(margins[2], out _marginLeft) && _marginLeft >= 0
                                    && int.TryParse(margins[3], out _marginRight) && _marginRight >= 0)
                                {
                                    return true;
                                }
                                ConsoleHelper.StdErr("命令行参数错误：-m参数后必须为用半角逗号分割开的正整数\n");
                                return false;
                            default:
                                ConsoleHelper.StdErr("命令行参数错误：-m参数后必须为1，2或4个用半角逗号分割开的正整数\n");
                                return false;
                        }
                    case "-T":
                        i++;
                        if (i == args.Length || args[i].ToLower() != "png" && args[i].ToLower() != "svg")
                        {
                            ConsoleHelper.StdErr("命令行参数错误：-T参数后必须为png或者svg之一\n");
                            return false;
                        }
                        _graphicsType = args[i].ToLower();
                        break;
                    case "-S":
                        i++;
                        if (i == args.Length)
                        {
                            ConsoleHelper.StdErr("命令行参数错误：-S参数后必须有正整数\n");
                            return false;
                        }
                        String[] sizes = args[i].Split(',');
                        switch (sizes.Length)//根据不同的命令长度确定画布大小参数
                        {
                            case 1:
                                if (int.TryParse(sizes[0], out _sizeWidth) && _sizeWidth >= 0)
                                {
                                    _sizeHeight = _sizeWidth;
                                    return true;
                                }
                                ConsoleHelper.StdErr("命令行参数错误：-S参数后必须为用半角逗号分割开的正整数\n");
                                return false;
                            case 2:
                                if (int.TryParse(sizes[0], out _sizeWidth) && _sizeWidth >= 0
                                    && int.TryParse(sizes[1], out _sizeHeight) && _sizeHeight >= 0)
                                {
                                    return true;
                                }
                                ConsoleHelper.StdErr("命令行参数错误：-S参数后必须为用半角逗号分割开的正整数\n");
                                return false;
                            default:
                                ConsoleHelper.StdErr("命令行参数错误：-S参数后必须为1或2个用半角逗号分割开的正整数\n");
                                return false;
                        }
                    default:
                        if (defaultNum > 1)
                        {
                            ConsoleHelper.StdErr("命令行参数错误：过多的参数\n");
                            return false; 
                        }
                        if (!FileHelper.IsFileExist(args[i]))
                        {
                            ConsoleHelper.StdErr("命令行参数错误：错误的文件路径\n");
                            return false;
                        }
                        _path = args[i];
                        defaultNum++;
                        break;
                }
            }
            if (defaultNum == 0)
            {
                ConsoleHelper.StdErr("命令行参数错误：必须指定文件路径\n");
                return false;
            }
            return true;
        }
    }
}
